<?php

/** @package codymvc */

/** 
 * @class TreeCommand
 * @brief Command that can call a method on itself based on the second URL segment.
 */

abstract class TreeCommand extends Command {

    /** Holds the URL segments */
    protected $segments;

    /**
     * Calls a method on this controller with the same name as the second URL segment
     * if it exists.
     * If no second URL segment is specified, uses 'home'.
     * If this is the default command, uses the first URL segment to determine
     * the method to call instead.  The default command is set using the 
     * 'default_command' config option.
     * If the first character is a digit, prepends an underscore to the method
     * name, as PHP cannot have function names starting with digits.
     * You cannot use 'execute' as the method to use.
     * If the method specified is not found, header redirects to /
     * @return (String) The output of the method called.  This should be the name
     *          of the template to use to display the output.
     */
    public function execute() {
        $method = 'home'; // default method
		
		$this->segments = self::get_url_segments();
		if ( count($this->segments) >= 2 && $this->segments[1] != '' ) {
		    $method = $this->segments[1];
		}
		if ( get_class($this) == CodyMVC::get_config('default_command') && count($this->segments) != 0 ) {
		    $method = $this->segments[0];
		}
        // Prepend underscore if the first character is a digit
        if ( is_numeric( substr($method,0,1) ) ) {
            $method = '_'.$method;
        }
	    $method = str_replace('-','_',strtolower($method));
        $available_methods = array();
        foreach( get_class_methods(get_class($this)) as $method_name ) {
            $method_name = strtolower($method_name);
            if ( $method_name == 'execute' ) continue; // avoid loop
            $available_methods[] = $method_name;
        }
	    if ( ! in_array(strtolower($method), $available_methods) && ! in_array('__call', $available_methods)) { 
			header("Location: /");
            return;
        }
        return $this->$method();
    }

    /**
     * Extracts the URL segments from the request URI.
     * @return (Array) An array of strings, each one representing a URL segment.
     *          The first URL segment is at index 0, etc.
     */
    public static function get_url_segments() {
		$request = parse_url($_SERVER['REQUEST_URI']);
        $path = $request['path'];
		if ( substr($path, -1) == '/' ) {
            // remove trailing slash
		    $path = substr($path, 0, -1);
		}
		$segments = explode('/',preg_replace('~/+~', '/', $path));
		array_shift($segments); // remove leading slash
		return $segments;
    }

}

?>
